package org.karelun.gef.parts;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.draw2d.AbsoluteBendpoint;
import org.eclipse.draw2d.ConnectionLayer;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.editparts.AbstractConnectionEditPart;
import org.eclipse.gef.editpolicies.ConnectionEndpointEditPolicy;
import org.eclipse.swt.SWT;
import org.karelun.gef.model.AbstractConnectionModel;
import org.karelun.gef.policies.CustomBendpointEditPolicy;
import org.karelun.gef.policies.DeleteConnectionEditPolicy;

public abstract class CustomAbstractConnectionEditPart extends
		AbstractConnectionEditPart implements PropertyChangeListener {

	protected void createEditPolicies() {
		installEditPolicy(EditPolicy.CONNECTION_ROLE,
				new DeleteConnectionEditPolicy());
		installEditPolicy(EditPolicy.CONNECTION_BENDPOINTS_ROLE,
				new CustomBendpointEditPolicy());
		installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE,
				new ConnectionEndpointEditPolicy());
	}

	abstract protected IFigure createFigure();
	
	public void activate() {
		super.activate();
		((AbstractConnectionModel) getModel()).addPropertyChangeListener(this);
	}

	public void deactivate() {
		((AbstractConnectionModel) getModel())
				.removePropertyChangeListener(this);
		super.deactivate();
	}

	public void propertyChange(PropertyChangeEvent evt) {
		if (evt.getPropertyName().equals(AbstractConnectionModel.P_BEND_POINT))
			refreshBendpoints();
	}

	protected void refreshBendpoints() {
		AbstractConnectionModel model = (AbstractConnectionModel) getModel();
		List<Point> bendPoints = model.getBendPoints();
		List<AbsoluteBendpoint> constraint = new ArrayList<AbsoluteBendpoint>();
		for (int i = 0; i < bendPoints.size(); i++) {
			Point point = bendPoints.get(i);
			AbsoluteBendpoint bendPoint = new AbsoluteBendpoint(point);
			constraint.add(bendPoint);
			getConnectionFigure().setRoutingConstraint(constraint);
		}
	}

	protected void refreshVisual() {
		refreshBendpoints();
		ConnectionLayer clayer = (ConnectionLayer) getLayer(LayerConstants.CONNECTION_LAYER);
		if ((getViewer().getControl().getStyle() & SWT.MIRRORED) == 0)
			clayer.setAntialias(SWT.ON);
	}

	public void setSelected(int value) {
		super.setSelected(value);
		if (value != EditPart.SELECTED_NONE)
			((PolylineConnection) getFigure()).setLineWidth(3);
		else
			((PolylineConnection) getFigure()).setLineWidth(2);
	}

}
